#pragma once

#include <vector>
#include "Config.h"

struct Sample
{
    std::vector<double> feature, label;
    Sample();
    Sample(const std::vector<double> &feature, const std::vector<double> &label);
    void display();
};

struct Node
{
    double value{}, bias{}, bias_delta{};
    std::vector<double> weight, weight_delta;

    explicit Node(size_t nextLayerSize);
};

class Net
{
private:
    /* data */
    Node *inputLayer[Config::INNODE];
    Node *hiddenLayer[Config::HIDENODE];
    Node *outputLayer[Config::OUTNODE];

    void grad_zero();
    void forward();
    double calculateLoss(const std::vector<double> &label);
    void backward(const std::vector<double> &label);
    void revise(size_t batch_size);

public:
    Net(/* args */);
    ~Net();

    bool train(const std::vector<Sample> &trainDataSet);

    Sample predict(const std::vector<double> &feature);

    std::vector<Sample> predict(const std::vector<Sample> &predictDataSet);
};

Net::Net(/* args */)
{
}

Net::~Net()
{
}
